home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok24.lha / DME / SRC / source.zoo / cmd1.c < prev    next >
C/C++ Source or Header  |  1989-07-03  |  25KB  |  1,179 lines

  1.  
  2. /*
  3.  * CMD1.C   (was TEXT1.C)
  4.  *
  5.  *      (C)Copyright 1987 by Matthew Dillon,    All Rights Reserved
  6.  */
  7.  
  8. #include "defs.h"
  9.  
  10. #define nomemory()  { memoryfail = 1; }
  11.  
  12. char RecallBuf[256];
  13.  
  14. FastScrollRaster(dx, dy, l, t, w, h) /* patch to speed up scrolling */
  15. {
  16.    register struct RastPort *rp = Rp;
  17.    register UBYTE *depth = &rp->BitMap->Depth;
  18.    UBYTE old = *depth;
  19.  
  20.    Forbid();
  21.    if (BSline > Ep->Topline + Rows || BEline < Ep->Topline - 1)
  22.       *depth = 1;
  23.    (void)ScrollRaster(rp, dx, dy, l, t, w, h);
  24.    *depth = old;
  25.    Permit();
  26. }
  27.  
  28. setpen(line)
  29. {
  30.    register short pen = (Ep == BEp && line >= BSline && line <= BEline) ? 2 : 1;
  31.    if (Comlinemode)
  32.       pen = 1;
  33.    if(ScreenDepth == 1) {
  34.       SetAPen(Rp, 1);
  35.       if(pen == 1)
  36.          SetDrMd(Rp,JAM2);
  37.       else
  38.          SetDrMd(Rp,JAM2|INVERSVID);
  39.    } else
  40.       if (pen != Rp->FgPen)
  41.          SetAPen(Rp, pen);
  42. }
  43.  
  44. UBYTE *depthPtr, oldDepth;
  45. char   no_block;
  46.  
  47. text_init()
  48. {
  49.     register ED *e;
  50.     register ED *ep = Ep;
  51.     extern PROC *proc;
  52.  
  53.     text_switch(NULL);
  54.     e = (ED *)allocb(sizeof(ED));
  55.     if (e == NULL)
  56.         return(0);
  57.     bzero(e, sizeof(ED));
  58.     e->Win = Win;
  59.     if (ep) {
  60.         e->dirlock = DupLock(ep->dirlock);
  61.         e->Insertmode = ep->Insertmode;
  62.         e->IgnoreCase = ep->IgnoreCase;
  63.         e->Tabstop    = ep->Tabstop;
  64.         e->Wordwrap   = ep->Wordwrap;
  65.         if (ep->Font) {
  66.             e->Font = ep->Font;
  67.             ++e->Font->tf_Accessors;
  68.             SetFont(Win->RPort, e->Font);
  69.         }
  70.     } else {
  71.         e->dirlock = DupLock(proc->pr_CurrentDir);
  72.         e->Insertmode = 1;
  73.         e->Tabstop = 4;
  74.     }
  75.     e->Lines = 1;
  76.     e->Maxlines = 32;
  77.     e->List = (ubyte **)allocl(e->Maxlines);
  78.     e->List[0] = allocb(1);
  79.     e->List[0][0] = Current[0] = Clen = 0;
  80.     e->IWiny = 16;
  81.     AddHead(&DBase, e);
  82.     strcpy(e->Name, "unnamed");
  83.     Ep = e;
  84.     text_cursor(1);
  85.     return(1);
  86. }
  87.  
  88.  
  89. text_switch(win)
  90. WIN *win;
  91. {
  92.     register ED *e;
  93.  
  94.     if (win)
  95.         text_sync();
  96.     if (win) {
  97.         for (e = (ED *)DBase.mlh_Head; e->Node.mln_Succ; e = (ED *)e->Node.mln_Succ) {
  98.             if (e->Win == win) {
  99.                 Ep = e;
  100.                 Win = win;
  101.                 Rp = Win->RPort;
  102.                 text_load();
  103.                 if (!Ep->iconmode) {
  104.                     set_window_params();
  105.                     window_title();
  106.                 }
  107.                 return(1);
  108.             }
  109.         }
  110.         return(0);
  111.     }
  112. }
  113.  
  114.  
  115. text_sync()
  116. {
  117.     register ED *ep = Ep;
  118.     char redraw = 0;
  119.     short len;
  120.     ubyte *ptr;
  121.  
  122.     for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len)
  123.         Current[len] = '\0';
  124.     Clen = len + 1;
  125.     if (!Comlinemode) {
  126.         if (strlen(ep->List[ep->Line]) != Clen) {
  127.             if (ptr = allocb(Clen+1)) {
  128.                 ep->Modified = 1;
  129.                 Overide = 0;
  130.                 FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1);
  131.                 ep->List[ep->Line] = ptr;
  132.             } else {
  133.                 nomemory();
  134.                 strcpy(Current, ep->List[ep->Line]);
  135.                 Clen = strlen(Current);
  136.             }
  137.         } else {
  138.             if (strcmp(ep->List[ep->Line], Current)) {
  139.                 ep->Modified = 1;
  140.                 Overide = 0;
  141.             }
  142.         }
  143.         strcpy(ep->List[ep->Line], Current);
  144.     }
  145.     if (Nsu == 0) {
  146.         if (ep->Column - ep->Topcolumn >= Columns || ep->Column < ep->Topcolumn) {
  147.             redraw = 1;
  148.             ep->Topcolumn = ep->Column - (Columns>>1);
  149.             if (ep->Topcolumn < 0)
  150.                 ep->Topcolumn = 0;
  151.         }
  152.         if (ep->Line - ep->Topline >= Rows || ep->Line < ep->Topline) {
  153.             redraw = 1;
  154.             ep->Topline = ep->Line - (Rows>>1);
  155.             if (ep->Topline < 0)
  156.                 ep->Topline = 0;
  157.         }
  158.     }
  159.     while (ep->Column > Clen)
  160.         Current[Clen++] = ' ';
  161.     Current[Clen] = '\0';
  162.     if (redraw)
  163.         text_redisplay();
  164.     return((int)redraw);
  165. }
  166.  
  167. text_load()
  168. {
  169.     if (Comlinemode)
  170.         return(0);
  171.     strcpy(Current, Ep->List[Ep->Line]);
  172.     Clen = strlen(Current);
  173.     while (Ep->Column > Clen)
  174.         Current[Clen++] = ' ';
  175.     Current[Clen] = '\0';
  176. }
  177.  
  178. text_colno()
  179. {
  180.     return(Ep->Column);
  181. }
  182.  
  183. text_lineno()
  184. {
  185.     return(Ep->Line+1);
  186. }
  187.  
  188. text_lines()
  189. {
  190.     return(Ep->Lines);
  191. }
  192.  
  193. text_cols()
  194. {
  195.     return((int)Clen);
  196. }
  197.  
  198. text_imode()
  199. {
  200.     return(Ep->Insertmode);
  201. }
  202.  
  203. text_tabsize()
  204. {
  205.     return((int)Ep->Tabstop);
  206. }
  207.  
  208. ubyte *
  209. text_name()
  210. {
  211.     return(Ep->Name);
  212. }
  213.  
  214. text_uninit()
  215. {
  216.     register int i;
  217.     register ED *ep = Ep;
  218.  
  219.     PMKill(ep);
  220.     freelist(ep->List, ep->Lines);
  221.     FreeMem(ep->List, ep->Maxlines * sizeof(char *));
  222.  
  223.     if (BEp == ep) {
  224.         BEp = NULL;
  225.         BSline = BEline = -1;
  226.     }
  227.     Remove(ep);
  228.     if (ep->Font) {
  229.         SetFont(ep->Win->RPort, ep->Win->WScreen->RastPort.Font);
  230.         CloseFont(ep->Font);
  231.     }
  232.     UnLock(ep->dirlock);
  233.     FreeMem(ep, sizeof(ED));
  234.     if (((ED *)DBase.mlh_Head)->Node.mln_Succ) {
  235.         Ep = (ED *)DBase.mlh_Head;
  236.         text_load();
  237.     } else {
  238.         Ep = NULL;
  239.     }
  240. }
  241.  
  242. text_cursor(n)
  243. {
  244.    register ED *ep = Ep;
  245.    register short px,py;
  246.    register short block;
  247.    register short curlen;
  248.  
  249.    for(curlen = Clen-1;curlen > 0,Current[curlen] == ' ';curlen--);
  250.  
  251.    movetocursor();
  252.    block = (ep == BEp && ep->Line >= BSline && ep->Line <= BEline);
  253.    SetAPen(Rp,1);
  254.    if(n) {
  255.       SetDrMd(Rp,COMPLEMENT);
  256.       px = COL(ep->Column-ep->Topcolumn);
  257.       py = ROW(ep->Line-ep->Topline);
  258.       RectFill(Rp,px,py,px+Xsize-1,py+Ysize-1);
  259.    } else {
  260.       if(block && (ep->Column <= curlen) && (ScreenDepth == 1))
  261.          SetDrMd(Rp,INVERSVID|JAM2);
  262.       else
  263.          SetDrMd(Rp,JAM2);
  264.       if((ScreenDepth != 1) && block && !Comlinemode)
  265.          SetAPen(Rp,2);
  266.       if (ep->Column <= curlen)
  267.          Text(Rp, Current+ep->Column, 1);
  268.       else
  269.          Text(Rp, " ", 1);
  270.    }
  271.    SetDrMd(Rp, JAM2);
  272. }
  273.  
  274. /*
  275. text_cursor(n)
  276. {
  277.    register short block;
  278.    register onebp = (ScreenDepth == 1);
  279.  
  280.    movetocursor();
  281.    block = (Ep == BEp && Ep->Line >= BSline && Ep->Line <= BEline) ;
  282.  
  283.    if( (n && !onebp) || (n && !block) || (onebp && block && !n) )
  284.       SetDrMd(Rp, JAM2|INVERSVID);
  285.    else
  286.       SetDrMd(Rp, JAM2);
  287.  
  288.    if (Current[Ep->Column])
  289.       Text(Rp, Current+Ep->Column, 1);
  290.    else
  291.       if(onebp)
  292.    Text(Rp, " ", 1);
  293.    SetDrMd(Rp, JAM2);
  294. }
  295. */
  296.  
  297. text_position(col, row)
  298. {
  299.     register ED *ep = Ep;
  300.     text_sync();
  301.     if (col == 0)
  302.         col = -1;
  303.     ep->Column = ep->Topcolumn + col;
  304.     if (ep->Column > 254)
  305.         ep->Column = 254;
  306.     if (ep->Column < 0)
  307.         ep->Column = 0;
  308.     ep->Line = ep->Topline + row;
  309.     if (ep->Line >= ep->Lines)
  310.         ep->Line = ep->Lines - 1;
  311.     if (ep->Line < 0)
  312.         ep->Line = 0;
  313.     text_load();
  314.     text_sync();
  315. }
  316.  
  317. displayblock(on)
  318. {
  319.     register long start = Ep->Topline;
  320.     register long lines = BEline - BSline + 1;
  321.  
  322.     if (start < BSline)
  323.         start = BSline;
  324.     if (!on) {
  325.         BSline = BEline = -1;
  326.         BEp = NULL;
  327.     }
  328.     if (Ep == BEp)
  329.         text_displayseg(start - Ep->Topline, lines);
  330. }
  331.  
  332. text_redrawblock(ok)
  333. {
  334.     WIN *savewin = NULL;
  335.  
  336.     if (BEp) {
  337.         if (BEp != Ep) {
  338.             savewin = Ep->Win;
  339.             text_switch(BEp->Win);
  340.         }
  341.         if (BSline <= BEline && BSline >= 0 && BEline < Ep->Lines) {
  342.             if (!ok) {
  343.                 BEp = NULL;
  344.                 BSline = BEline = -1;
  345.             }
  346.             text_displayseg(0, Rows);
  347.         }
  348.         if (savewin)
  349.             text_switch(savewin);
  350.     }
  351.     if (!ok) {
  352.         BEp = NULL;
  353.         BSline = BEline = -1;
  354.     }
  355. }
  356.  
  357. text_displayseg(start, n)
  358. {
  359.     register short i, c;
  360.     register ubyte *ptr;
  361.     register ED *ep = Ep;
  362.     char ib;
  363.  
  364.     if (Nsu)
  365.         return(0);
  366.     for (i = start; i < start + n && i < Rows && ep->Topline + i < ep->Lines; ++i) {
  367.         if (Comlinemode) {
  368.             if (ep->Topline + i != ep->Line)
  369.                 continue;
  370.             ptr = Current;
  371.             SetAPen(Rp, 1);
  372.         } else {
  373.             ptr = ep->List[ep->Topline + i];
  374.             setpen(i+ep->Topline);
  375.         }
  376.         for (c = ep->Topcolumn; c && *ptr; ++ptr, --c);
  377.         c = strlen(ptr);
  378.         if (c) {
  379.             Move(Rp, COLT(0), ROWT(i));
  380.             Text(Rp, ptr, (c > Columns) ? Columns : c);
  381.         }
  382.     }
  383. }
  384.  
  385. extern short knob_modified;
  386.  
  387. text_redisplay()
  388. {
  389.    if (Nsu)
  390.      return(0);
  391.    SetAPen(Rp, 0);
  392.    if (Comlinemode)
  393.      RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs);
  394.    else
  395.      RectFill(Rp, Xbase, Ybase, Xbase + Xpixs, Ybase + Ypixs);
  396.    text_displayseg(0,Rows);
  397.    /*
  398.    if(knob_modified)
  399.    */
  400.       set_prop();
  401. }
  402.  
  403. text_redisplaycurrline()
  404. {
  405.     int row = Ep->Line - Ep->Topline;
  406.  
  407.     if (Nsu)
  408.         return(0);
  409.     SetAPen(Rp, 0);
  410.     RectFill(Rp, COL(0), ROW(row), Xbase+Xpixs, ROW(row+1)-1);
  411.     text_displayseg(row, 1);
  412. }
  413.  
  414. text_write(str)
  415. ubyte *str;
  416. {
  417.     register short len = strlen(str);
  418.     register short i;
  419.     register ED *ep = Ep;
  420.  
  421.     if (Clen + len >= 255) {
  422.         text_sync();
  423.         text_load();
  424.     }
  425.     if (ep->Insertmode == 0) {
  426.         if (ep->Column + len >= 255)
  427.             goto fail;
  428.         bmov(str, Current + ep->Column, len);
  429.         if (ep->Column + len >= Clen)
  430.             Clen = ep->Column + len;
  431.         Current[Clen] = 0;
  432.     } else {
  433.         if (Clen + len >= 255)
  434.             goto fail;
  435.         bmov(Current + ep->Column, Current + ep->Column + len, Clen+1-ep->Column);
  436.         bmov(str, Current + ep->Column, len);
  437.         Clen += len;
  438.         if (len < Columns - (ep->Column - ep->Topcolumn)) {
  439.             FastScrollRaster( -len * Xsize, 0 ,
  440.                 COL(ep->Column - ep->Topcolumn),
  441.                 ROW(ep->Line - ep->Topline),
  442.                 COL(Columns) - 1,
  443.                 ROW(ep->Line - ep->Topline + 1) - 1
  444.             );
  445.         }
  446.     }
  447.     i = (ep->Column - ep->Topcolumn + len > Columns) ? Columns - ep->Column + ep->Topcolumn : len;
  448.     setpen(ep->Line);
  449.     Move(Rp, COLT(ep->Column - ep->Topcolumn), ROWT(ep->Line - ep->Topline));
  450.     Text(Rp, str, i);
  451.     ep->Column += len;
  452.     if (ep->Column - ep->Topcolumn >= Columns)
  453.         text_sync();
  454. fail:
  455.     if (Comlinemode == 0 && ep->Wordwrap)
  456.         do_reformat(0);
  457. }
  458.  
  459. do_up()
  460. {
  461.     if (Ep->Line) {
  462.         text_sync();
  463.         --Ep->Line;
  464.         text_load();
  465.         if (Ep->Line < Ep->Topline) {
  466.             if (Nsu == 0) {
  467.                 FastScrollRaster(0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  468.                 --Ep->Topline;
  469.                 SetPropKnob();
  470.                 text_displayseg(0, 1);
  471.             }
  472.         }
  473.     } else {
  474.         Abortcommand = 1;
  475.     }
  476. }
  477.  
  478. do_scrolldown()
  479. {
  480.     if (Ep->Topline + Rows < Ep->Lines) {
  481.         if (Nsu == 0) {
  482.             text_sync();
  483.             FastScrollRaster(0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  484.             ++Ep->Topline;
  485.             ++Ep->Line;
  486.             text_load();
  487.             SetPropKnob();
  488.             text_displayseg(Rows-1, 1);
  489.         }
  490.     } else {
  491.         Abortcommand = 1;
  492.     }
  493. }
  494.  
  495. do_scrollup()
  496. {
  497.     if (Ep->Topline) {
  498.         if (Nsu == 0) {
  499.             text_sync();
  500.             FastScrollRaster(0,-Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  501.             --Ep->Topline;
  502.             --Ep->Line;
  503.             text_load();
  504.             SetPropKnob();
  505.             text_displayseg(0, 1);
  506.         }
  507.     } else {
  508.         Abortcommand = 1;
  509.     }
  510. }
  511.  
  512. do_down()
  513. {
  514.     if (Ep->Line + 1 < Ep->Lines) {
  515.         text_sync();
  516.         ++Ep->Line;
  517.         text_load();
  518.         if (Ep->Line - Ep->Topline >= Rows) {
  519.             if (Nsu == 0) {
  520.                 FastScrollRaster(0,Ysize,COL(0),ROW(0),COL(Columns)-1,ROW(Rows)-1);
  521.                 ++Ep->Topline;
  522.                 SetPropKnob();
  523.                 text_displayseg(Rows-1, 1);
  524.             }
  525.         }
  526.     } else {
  527.         Abortcommand = 1;
  528.     }
  529. }
  530.  
  531.  
  532. /*
  533.  *  PAGEUP
  534.  *  PAGEDOWN
  535.  *  PAGESET n   (n = 0 to 100 for percentage of #rows to scroll, minimum 1)
  536.  *              can be > 100.
  537.  */
  538.  
  539. do_page()
  540. {
  541.     register int n, multiplier = 1;
  542.     register ED *ep = Ep;
  543.     static short pctg = 80;
  544.  
  545.     switch(av[0][4]) {
  546.     case 'u':
  547.         multiplier = -1;
  548.     case 'd':
  549.         n = multiplier * Rows * pctg / 100;
  550.         if (!n)
  551.             n = multiplier;
  552.         if (n > 0 && ep->Topline >= ep->Lines - Rows) {
  553.             Abortcommand = 1;
  554.             return(0);
  555.         }
  556.         text_sync();
  557.         ep->Line += n;
  558.         ep->Topline += n;
  559.         if (ep->Line >= ep->Lines)
  560.             ep->Line = ep->Lines - 1;
  561.         if (ep->Line < 0)
  562.             ep->Line = 0;
  563.         if (ep->Topline >= ep->Lines) {
  564.             ep->Topline = ep->Lines - Rows - 1;
  565.             Abortcommand = 1;
  566.         }
  567.         if (ep->Topline < 0) {
  568.             ep->Topline = 0;
  569.             Abortcommand = 1;
  570.         }
  571.         text_load();
  572.         if (!text_sync())
  573.             text_redisplay();
  574.         break;
  575.     case 's':
  576.         pctg = atoi(av[1]);
  577.         break;
  578.     }
  579. }
  580.  
  581.  
  582. do_downadd()
  583. {
  584.     ubyte *ptr;
  585.  
  586.     if (Ep->Line + 1 == Ep->Lines) {
  587.         Ep->Modified = 1;
  588.         if (makeroom(32) && (ptr = allocb(1))) {
  589.             Ep->List[Ep->Lines] = ptr;
  590.             *ptr = 0;
  591.             ++Ep->Lines;
  592.         } else {
  593.             nomemory();
  594.         }
  595.     }
  596.     do_down();
  597. }
  598.  
  599.  
  600. do_left()
  601. {
  602.     if (Ep->Column) {
  603.         --Ep->Column;
  604.         if (Ep->Column < Ep->Topcolumn)
  605.             text_sync();
  606.     } else {
  607.         Abortcommand = 1;
  608.     }
  609. }
  610.  
  611. do_right()
  612. {
  613.     if (Ep->Column != 254) {
  614.         if (Current[Ep->Column] == 0) {
  615.             Current[Ep->Column] = ' ';
  616.             Current[Ep->Column+1]= '\0';
  617.             ++Clen;
  618.         }
  619.         ++Ep->Column;
  620.         if (Ep->Column - Ep->Topcolumn >= Columns)
  621.             text_sync();
  622.     } else {
  623.         Abortcommand = 1;
  624.     }
  625. }
  626.  
  627. do_tab()
  628. {
  629.     register short n;
  630.  
  631.     for (n = Ep->Tabstop-(Ep->Column % Ep->Tabstop); n > 0; --n)
  632.         do_right();
  633. }
  634.  
  635. do_backtab()
  636. {
  637.     register short n;
  638.  
  639.     n = Ep->Column % Ep->Tabstop;
  640.     if (!n)
  641.         n = Ep->Tabstop;
  642.     for (; n > 0; --n)
  643.         do_left();
  644. }
  645.  
  646. do_return()
  647. {
  648.     ubyte buf[256];
  649.     char *partial;
  650.  
  651.     if (Comlinemode) {
  652.         strcpy(buf, Current);
  653.         strcpy(RecallBuf, Current);
  654.         partial = Partial;
  655.         Partial = NULL;
  656.         escapecomlinemode();
  657.         if (partial) {
  658.             if (do_command(buf))
  659.                 do_command(partial);
  660.             free(partial);
  661.         } else {
  662.             do_command(buf);
  663.         }
  664.     } else {
  665.         Ep->Column = 0;
  666.         text_sync();
  667.         do_downadd();
  668.     }
  669. }
  670.  
  671. do_bs()
  672. {
  673.     register ED *ep = Ep;
  674.     if (ep->Column) {
  675.         bmov(Current + ep->Column, Current + ep->Column - 1, Clen - ep->Column + 1);
  676.         --ep->Column;
  677.         --Clen;
  678.         if (ep->Column < ep->Topcolumn) {
  679.             text_sync();
  680.         } else {
  681.             FastScrollRaster(Xsize, 0,
  682.                 COL(ep->Column - ep->Topcolumn),
  683.                 ROW(ep->Line   - ep->Topline),
  684.                 COL(Columns)-1,
  685.                 ROW(ep->Line - ep->Topline + 1)-1
  686.             );
  687.             if (Clen >= ep->Topcolumn + Columns) {
  688.                 setpen(ep->Line);
  689.                 Move(Rp, COLT(Columns-1), ROWT(ep->Line - ep->Topline));
  690.                 Text(Rp, Current + ep->Topcolumn + Columns - 1, 1);
  691.             }
  692.         }
  693.         if (Comlinemode == 0 && ep->Wordwrap)
  694.             do_reformat(0);
  695.     } else {
  696.         Abortcommand = 1;
  697.     }
  698. }
  699.  
  700.  
  701. /*
  702.  * esc, escimm
  703.  */
  704.  
  705. int Savetopline, Savecolumn, Savetopcolumn;
  706.  
  707. do_recall()
  708. {
  709.     av[0] = (ubyte *)"escimm";
  710.     av[1] = (ubyte *)RecallBuf;
  711.     do_esc();
  712. }
  713.  
  714. do_esc()
  715. {
  716.     register ED *ep = Ep;
  717.  
  718.     if (Comlinemode)
  719.         return(escapecomlinemode());
  720.     text_sync();
  721.     if (av[0][3] == 'i')
  722.         strcpy(Current, av[1]);
  723.     else
  724.         Current[0] = 0;
  725.     Clen = strlen(Current);
  726.     Comlinemode = 1;
  727.     returnoveride(1);
  728.     Savetopline = ep->Topline;
  729.     Savecolumn  = ep->Column;
  730.     Savetopcolumn = ep->Topcolumn;
  731.     ep->Column    = Clen;
  732.     ep->Topcolumn = 0;
  733.     ep->Topline   = ep->Line - Rows + 1;
  734.     SetAPen(Rp, 0);
  735.     RectFill(Rp, COL(0), ROW(Rows-1), Xbase+Xpixs, Ybase+Ypixs);
  736.     SetAPen(Rp, 1);
  737.     Move(Rp, COL(0), ROW(Rows-1) - 1);
  738.     Draw(Rp, Xbase + Xpixs, ROW(Rows-1) - 1);
  739.     text_displayseg(Rows-1,1);
  740. }
  741.  
  742.  
  743. escapecomlinemode()
  744. {
  745.     register ED *ep = Ep;
  746.  
  747.     if (Partial) {
  748.         free(Partial);
  749.         Partial = NULL;
  750.     }
  751.     if (Comlinemode) {
  752.         strcpy(RecallBuf, Current);
  753.         Comlinemode = 0;
  754.         returnoveride(0);
  755.         ep->Topline = Savetopline;
  756.         ep->Column  = Savecolumn;
  757.         ep->Topcolumn = Savetopcolumn;
  758.         text_load();
  759.         SetAPen(Rp, 0);
  760.         RectFill(Rp, COL(0), ROW(Rows-1)-1, Xbase+Xpixs, Ybase+Ypixs);
  761.         SetAPen(Rp, 1);
  762.         text_displayseg(Rows-2,2);
  763.     }
  764. }
  765.  
  766.  
  767. do_del()
  768. {
  769.     register ED *ep = Ep;
  770.  
  771.     if (Current[ep->Column]) {
  772.         bmov(Current + ep->Column + 1, Current + ep->Column, Clen - ep->Column);
  773.         --Clen;
  774.         FastScrollRaster(Xsize, 0,
  775.             COL(ep->Column - ep->Topcolumn),
  776.             ROW(ep->Line - ep->Topline),
  777.             COL(Columns)-1,
  778.             ROW(ep->Line - ep->Topline + 1) - 1
  779.         );
  780.         if (Clen >= ep->Topcolumn + Columns) {
  781.             setpen(ep->Line);
  782.             Move(Rp, COLT(Columns-1), ROWT(ep->Line-ep->Topline));
  783.             Text(Rp, Current+ep->Topcolumn+Columns-1, 1);
  784.         }
  785.         if (Comlinemode == 0 && ep->Wordwrap)
  786.             do_reformat(0);
  787.     }
  788. }
  789.  
  790. do_top()
  791. {
  792.     text_sync();
  793.     Ep->Line = 0;
  794.     text_load();
  795.     text_sync();
  796. }
  797.  
  798. do_bottom()
  799. {
  800.     text_sync();
  801.     Ep->Line = Ep->Lines - 1;
  802.     text_load();
  803.     text_sync();
  804. }
  805.  
  806. do_firstcolumn()
  807. {
  808.     if (Ep->Column) {
  809.         Ep->Column = 0;
  810.         text_sync();
  811.     }
  812. }
  813.  
  814. do_firstnb()
  815. {
  816.     for (Ep->Column = 0; Current[Ep->Column] == ' '; ++Ep->Column);
  817.     if (Current[Ep->Column] == 0)
  818.         Ep->Column = 0;
  819.     text_sync();
  820. }
  821.  
  822. do_lastcolumn()
  823. {
  824.     short i;
  825.  
  826.     text_sync();
  827.     i = (Comlinemode) ? Clen : strlen(Ep->List[Ep->Line]);
  828.     if (i != Ep->Column) {
  829.         Ep->Column = i;
  830.         text_sync();
  831.     }
  832. }
  833.  
  834. /*
  835.  * GOTO [+/-]N
  836.  * GOTO BLOCK   start of block
  837.  * GOTO START   start of block
  838.  * GOTO END     end of block
  839.  */
  840.  
  841. do_goto()
  842. {
  843.     register short n, i;
  844.     register ubyte *ptr = av[1];
  845.  
  846.     i = 0;
  847.     n = -1;
  848.  
  849.     switch(*ptr) {
  850.     case 'b':
  851.     case 's':
  852.     case 'B':
  853.     case 'S':
  854.         n = -1;
  855.         if (Ep == BEp)
  856.             n = BSline;
  857.         break;
  858.     case 'e':
  859.     case 'E':
  860.         n = -1;
  861.         if (Ep == BEp)
  862.             n = BEline;
  863.         break;
  864.     case '+':
  865.         i = 1;
  866.     case '-':
  867.         n = Ep->Line;
  868.     default:
  869.         n += atoi(ptr+i);
  870.     }
  871.     if (n >= Ep->Lines)
  872.         n = Ep->Lines - 1;
  873.     if (n < 0)
  874.         n = 0;
  875.     text_sync();
  876.     Ep->Line = n;
  877.     text_load();
  878.     text_sync();
  879. }
  880.  
  881. do_screentop()
  882. {
  883.     text_sync();
  884.     Ep->Line = Ep->Topline;
  885.     text_load();
  886.     text_sync();
  887. }
  888.  
  889. do_screenbottom()
  890. {
  891.     text_sync();
  892.     Ep->Line = Ep->Topline + Rows - 1;
  893.     if (Ep->Line < 0 || Ep->Line >= Ep->Lines)
  894.         Ep->Line = Ep->Lines - 1;
  895.     text_load();
  896.     text_sync();
  897. }
  898.  
  899. ubyte Fstr[256];
  900. ubyte Rstr[256];
  901. short Srch_sign;
  902. char  Doreplace;
  903. char  Multimode;
  904.  
  905. /*
  906.  * multi-replace
  907.  */
  908.  
  909. multireplace(im)
  910. IMESS *im;
  911. {
  912.    ubyte buf[2];
  913.    short blen = 0;
  914.  
  915.    blen = DeadKeyConvert(im, buf, 2, NULL);
  916.    if(blen == 1) {
  917.       switch(buf[0]) {
  918.          case 'a':do {
  919.                      Doreplace = 1;
  920.                      Multimode = 1;
  921.                      search_operation();
  922.                      if(!Abortcommand)
  923.                         Doreplace = 0;
  924.                         Srch_sign = 1;
  925.                         search_operation();
  926.                   } while(!Abortcommand && !breakcheck());
  927.                   Ep->Replacemode = 0;
  928.                   Multimode = 0;
  929.                   window_title();
  930.                   break;
  931.          case 'y':Doreplace = 1;
  932.                   Multimode = 1;
  933.                   search_operation();
  934.                   if(Abortcommand)
  935.                      break;
  936.          case 'n':Doreplace = 0;
  937.                   Multimode = 0;
  938.                   Srch_sign = 1;
  939.                   search_operation();
  940.                   if(!Abortcommand)
  941.                      text_cursor(1);
  942.                   break;
  943.          case  3 :/* Ctrl-C */
  944.          case 'q':Ep->Replacemode = 0;
  945.                   Multimode = 0;
  946.                   window_title();
  947.                   return 0;
  948.       }
  949.    }
  950.    if(Abortcommand) {
  951.       Multimode = 0;
  952.       Ep->Replacemode = 0;
  953.       window_title();
  954.    }
  955.    if(Ep->Replacemode)
  956.       title("Replace ? (y/n/a/q)");
  957. }
  958.  
  959. do_multireplace()
  960. {
  961.    Doreplace = 0;
  962.    Srch_sign = 1;
  963.    strcpy(Fstr, av[1]);
  964.    strcpy(Rstr, av[2]);
  965.    search_operation();
  966.    text_cursor(1);
  967.    if(!Abortcommand) {
  968.      Ep->Replacemode = 1;
  969.      title("Replace ? (y/n/a/q)");
  970.    }
  971.    text_cursor(1);
  972. }
  973.  
  974. /*
  975.  * findstr, repstr
  976.  */
  977.  
  978. do_findstr()
  979. {
  980.     if (av[0][0] == 'f')
  981.         strcpy(Fstr, av[1]);
  982.     else
  983.         strcpy(Rstr, av[1]);
  984. }
  985.  
  986. /*
  987.  * findr, nextr, prevr
  988.  */
  989.  
  990. do_findr()
  991. {
  992.     Doreplace = 1;
  993.     Srch_sign = 1;
  994.     Multimode = 0;
  995.     switch(av[0][0]) {
  996.     case 'f':
  997.         strcpy(Fstr, av[1]);
  998.         strcpy(Rstr, av[2]);
  999.         break;
  1000.     case 'p':
  1001.         Srch_sign = -1;
  1002.         break;
  1003.     }
  1004.     search_operation();
  1005. }
  1006.  
  1007. /*
  1008.  * find, next, prev
  1009.  */
  1010.  
  1011. do_find()
  1012. {
  1013.     Doreplace = 0;
  1014.     Srch_sign = 1;
  1015.     Multimode = 0;
  1016.     switch(av[0][0]) {
  1017.     case 'f':
  1018.         strcpy(Fstr, av[1]);
  1019.         break;
  1020.     case 'p':
  1021.         Srch_sign = -1;
  1022.         break;
  1023.     }
  1024.     search_operation();
  1025. }
  1026.  
  1027.  
  1028. static char CaseIgnore;
  1029.  
  1030. void
  1031. search_operation()
  1032. {
  1033.     int flen = strlen(Fstr);
  1034.     int rlen = strlen(Rstr);
  1035.     char senabled = 0;
  1036.     register ubyte *ptr;
  1037.     register int i, col;
  1038.     register ED *ep = Ep;
  1039.  
  1040.     CaseIgnore = ep->IgnoreCase;
  1041.     text_sync();
  1042.     if (!flen) {
  1043.         title("No find pattern");
  1044.         Abortcommand = 1;
  1045.         return;
  1046.     }
  1047.     col = ep->Column;
  1048.     if (col >= strlen(ep->List[ep->Line]))
  1049.         col = strlen(ep->List[ep->Line]);
  1050.  
  1051.     i = ep->Line;
  1052.  
  1053.     if(Multimode) {
  1054.       senabled = 1;
  1055.       if(Doreplace)
  1056.           goto found;
  1057.     }
  1058.  
  1059.     for (;;) {
  1060.         ptr = ep->List[i];
  1061.         if (Srch_sign > 0) {
  1062.             while (ptr[col]) {
  1063.                 if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  1064.                     goto found;
  1065.                 senabled = 1;
  1066.                 ++col;
  1067.             }
  1068.             senabled = 1;
  1069.             if (++i >= ep->Lines)
  1070.                 break;
  1071.             col = 0;
  1072.         } else {
  1073.             while (col >= 0) {
  1074.                 if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  1075.                     goto found;
  1076.                 senabled = 1;
  1077.                 --col;
  1078.             }
  1079.             senabled = 1;
  1080.             if (--i < 0)
  1081.                 break;
  1082.             col = strlen(ep->List[i]);
  1083.         }
  1084.     }
  1085.     title("Pattern Not Found");
  1086.     Abortcommand = 1;
  1087.     return;
  1088.  
  1089. found:
  1090.     ep->Line = i;
  1091.     ep->Column = col;
  1092.  
  1093.     text_load();
  1094.     if (Doreplace) {
  1095.         if (rlen > flen && rlen-flen+strlen(ptr) > 254) {
  1096.             title("Replace: Line Too Long");
  1097.             Abortcommand = 1;
  1098.             return;
  1099.         }
  1100.         if (Clen-col-flen >= 0) {
  1101.             bmov(Current+col+flen, Current+col+rlen, Clen-col-flen+1);
  1102.             bmov(Rstr, Current+col, rlen);
  1103.             Clen += rlen-flen;
  1104.             ep->Column += rlen;
  1105.         }
  1106.         Ep->Modified = 1;
  1107.         text_sync();
  1108.         text_redisplaycurrline();
  1109.     } else {
  1110.         text_sync();
  1111.         if(Ep->Replacemode) {
  1112.             text_cursor(0);
  1113.             text_cursor(1);
  1114.         }
  1115.     }
  1116. }
  1117.  
  1118. #asm
  1119.  
  1120.          XDEF     _sprintf
  1121.          XDEF     _case_strncmp
  1122.  
  1123. _LVORawDoFmt EQU -522
  1124.  
  1125. _sprintf:
  1126.          movem.l  a2/a3/a6,-(sp)
  1127.          move.l   4*4(sp),a3
  1128.          move.l   5*4(sp),a0
  1129.          lea.l    6*4(sp),a1
  1130.          lea.l    stuffChar(pc),a2
  1131.          move.l   4,a6
  1132.          jsr      _LVORawDoFmt(a6)
  1133.          movem.l  (sp)+,a2/a3/a6
  1134.          rts
  1135.  
  1136. stuffChar:
  1137.          move.b    d0,(a3)+
  1138.          rts
  1139.  
  1140.                 ;   NOTE: assumes that one of the strings is at least
  1141.                 ;         'len' bytes long, and contains no nulls.  Also,
  1142.                 ;         returns only 0=success, 1=fail.  NOT A TRUE
  1143.                 ;         CASE COMPARE... can get confused by control
  1144.                 ;         chars.
  1145.                 ;
  1146.                 ;   4(sp)  = s1
  1147.                 ;   8(sp)  = s2
  1148.                 ;   12(sp) = len
  1149.  
  1150. _case_strncmp:
  1151.                 movem.l 4(sp),A0/A1
  1152.                 move.l  12(sp),D0
  1153.                 move.l  D2,-(sp)
  1154.                 tst.b   _CaseIgnore
  1155.                 bne     .csc100
  1156.                 moveq.l #0,D1           ;set Z bit      case sensitive
  1157.                 bra     .csc20
  1158. .csc10          cmpm.b  (A0)+,(A1)+
  1159. .csc20          dbne    D0,.csc10
  1160.                 bne     .cscfail
  1161. .cscsucc        moveq.l #0,D0           ;return true
  1162.                 move.l  (sp)+,D2
  1163.                 rts
  1164.  
  1165. .csc100         moveq.l #0,D1           ;set Z bit      case sensitive
  1166.                 bra     .csc120
  1167. .csc110         move.b  (A0)+,D1        ;XOR two bytes together
  1168.                 move.b  (A1)+,D2
  1169.                 eor.b   D2,D1
  1170.                 and.b   #$DF,D1         ;forget bit 5 (the case)
  1171. .csc120         dbne    D0,.csc110
  1172.                 beq     .cscsucc
  1173. .cscfail        moveq.l #1,D0           ;return failure
  1174.                 move.l  (sp)+,D2
  1175.                 rts
  1176.  
  1177. #endasm
  1178.  
  1179.